package lzw;


import java.io.IOException;
import java.io.InputStream;




public class Input extends InputOutput{
        
        private InputStream in;
        /**
         * Number of codes actually stored in the buffer.
         */
        private int bufferedCodes;

        public Input(InputStream in, int codeWordLength) {
            this.in = in;
            this.codeWordLength = codeWordLength;
            bufferedCodes = 0;
            buffer = 0;
            bufferUsageBits = (int) Euclid.leastCommonMultiple(BYTE_SIZE, codeWordLength);
            bufferUsageBytes = bufferUsageBits / BYTE_SIZE;
            bufferUsageSymbols = bufferUsageBits / codeWordLength;
            mask = (1 << codeWordLength) - 1;
        }

        public int read() throws IOException {
            if((bufferedCodes <= 0) && (!eof)) {
                buffer = 0;
                for(int i = 0; i < bufferUsageBytes; i++) {
                    int read = in.read();
                    if(-1 == read) {
                        eof = true;
                    }
                    read = read & BYTE_MASK;
                    read <<= i * BYTE_SIZE;
                    buffer |= read;
                }
                bufferedCodes = bufferUsageSymbols;
            }
            if (bufferedCodes > 0) {
                int code = (int) (buffer & mask);
                buffer >>= codeWordLength;
                bufferedCodes--;
                if (code < (1 << codeWordLength) - 1) {
                    return code;
                } else {
                    return -1;
                }
            } else {
                return -1;
            }
        }
        
        public void close() throws IOException {
            in.close();
        }
}